<template>
  <div class="container">
    <p
      >-------------------------------------------------- 字 谜
      --------------------------------------------------</p
    >
    <textarea v-model="zimiText"></textarea>
    <button @click="getZimiText">转换</button>
    <input type="file" @change="handleFileChange" accept="video/*" multiple />
    <button @click="endZimiVideo">生成视频</button>
    <button @click="handleOneVideo">导出视频</button>
    <div style="display: flex; justify-content: space-between">
      <div
        v-for="(item, i) in zimiArray"
        :key="i"
        style="flex: 1; margin-right: 10px"
      >
        <p>{{ item.zimi }}</p>
        <video
          :src="item.url"
          type="video/mp4"
          controls
          style="width: 100%; margin-top: 10px"
        />
      </div>
    </div>
    <div style="display: flex; justify-content: space-between">
      <div
        v-for="(item, i) in showVideoZimi"
        :key="i"
        style="flex: 1; margin-right: 10px"
      >
        <p>{{ item.zimi }}</p>
        <video
          :src="item.newUrl"
          type="video/mp4"
          controls
          style="width: 100%; margin-top: 10px"
        />
      </div>
    </div>
    <a-modal v-model:visible="visible" @ok="handleOk">
      <template #title> 请输入对联 </template>
      <div>
        <textarea v-model="allZimi" placeholder="请输入字谜"></textarea>
      </div>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import {
  MP4Clip,
  Combinator,
  ImgClip,
  OffscreenSprite,
  renderTxt2ImgBitmap,
} from '@webav/av-cliper';
import allZimiArray from './zimi.ts';
const allZimi = ref<string>('');
const zimiText = ref('');
const zimiArray = ref([]); // 所有字谜数组
const showVideoZimi = ref([]); // 生成好的视频
const visible = ref(false);
// 导出视频
const handleOneVideo = () => {
  if (!showVideoZimi.value.length) {
    alert('请先生成视频');
    return;
  }
  for (const key in showVideoZimi.value) {
    let link = document.createElement('a');
    link.href = showVideoZimi.value[key].newUrl;
    link.download = `${Date.now()}-${key * 1 + 1}.mp4`;
    link.click();
  }
};
const handleOk = () => {
  getOneZimi();
  visible.value = false;
};
// 上传视频文件
const handleFileChange = (event: any) => {
  zimiArray.value = [];
  const files = Array.from(event.target.files);
  files.forEach(async (file: any,index) => {
    let pushData = {
      width: 0,
      height: 0,
      url: '',
      newUrl: '',
      zimi: '',
      imgUrl: '',
    };
    if (file && file.type.startsWith('video/')) {
      // 确保文件是视频类型
      const resp1 = await fetch(URL.createObjectURL(file));
      new MP4Clip(resp1.body!).ready.then(async (info) => {
        pushData.url = URL.createObjectURL(file); // 创建可访问的URL
        pushData.width = info.width;
        pushData.height = info.height;
        zimiArray.value.push(pushData);
        getOneZimi(pushData);
      });
    }
  });
  // visible.value = true;
};
// 处理视频和图片
const endZimiVideo = async (info) => {
  console.log(info);
  if (info) {
    const videoInfo = info;
    const resp1 = await fetch(videoInfo.url);
    const clip = await new MP4Clip(resp1.body!);
    const spr1 = new OffscreenSprite(clip);
    spr1.flip = 'horizontal'; // 镜像处理视频
    let spr2 = null;
    spr2 = new OffscreenSprite(
      new ImgClip((await fetch(videoInfo.imgUrl)).body)
    );
    const com = new Combinator({
      width: videoInfo.width,
      height: videoInfo.height,
    });
    await com.addSprite(spr1, { main: true });
    await com.addSprite(spr2);
    const srcBlob = await new Response(com?.output() ?? null).blob();
    const link = document.createElement('a');
    link.href = URL.createObjectURL(srcBlob);
    link.download = `${Date.now()}-${info.zimi}.mp4`;
    link.click();
  } else {
    zimiArray.value.forEach(async (videoInfo, index) => {
      if (videoInfo.imgUrl !== '') {
        const resp1 = await fetch(videoInfo.url);
        const clip = await new MP4Clip(resp1.body!);
        const spr1 = new OffscreenSprite(clip);
        let spr2 = null;
        spr2 = new OffscreenSprite(
          new ImgClip((await fetch(videoInfo.imgUrl)).body)
        );
        const com = new Combinator({
          width: videoInfo.width,
          height: videoInfo.height,
        });
        await com.addSprite(spr1, { main: true });
        await com.addSprite(spr2);
        const srcBlob = await new Response(com?.output() ?? null).blob();
        videoInfo.newUrl = URL.createObjectURL(srcBlob);
        showVideoZimi.value.push(videoInfo);
      }
    });
  }
};
const getZimiText = () => {
  const parts = zimiText.value
    .match(/"([^"]*)"/g)
    .map((part) => part.slice(1, -1));
  console.log(parts);
};
// 获取单个字谜数据
const getOneZimi = (info) => {
  if (info) {
    const canvas = document.createElement('canvas');
    canvas.width = info.width; // 画布宽
    canvas.height = info.height; // 画布高
    // zimiArray.value[index].zimi = part;
    const ctx = canvas.getContext('2d');
    ctx.font = 'bold 150px Arial'; // 设置字体大小和类型
    ctx.fillStyle = '#FCDF00'; // 设置填充颜色，即文字颜色
    ctx.strokeStyle = 'black'; // 设置描边颜色
    ctx.lineWidth = 30; // 设置描边宽度
    ctx.textBaseline = 'middle'; // 设置文字基线为中间
    ctx.textAlign = 'center'; // 设置文字对齐方式为居中
    ctx.strokeText('赏你五千万也', canvas.width / 2, canvas.height / 2 - 700);
    ctx.fillText('赏你五千万也', canvas.width / 2, canvas.height / 2 - 700);
    // footer
    ctx.strokeText('猜不出', canvas.width / 2, canvas.height / 2 - 500);
    ctx.fillText('猜不出', canvas.width / 2, canvas.height / 2 - 500);
    ctx.strokeText('猜四个字', canvas.width / 2, canvas.height / 2 + 750);
    ctx.fillText('猜四个字', canvas.width / 2, canvas.height / 2 + 750);
    // 设置文字样式
    ctx.font = 'bold 180px Arial'; // 设置字体大小和类型
    ctx.fillStyle = 'white'; // 设置填充颜色，即文字颜色
    ctx.strokeStyle = 'red'; // 设置描边颜色
    ctx.lineWidth = 20; // 设置描边宽度
    ctx.textBaseline = 'middle'; // 设置文字基线为中间
    ctx.textAlign = 'center'; // 设置文字对齐方式为居中
    info.zimi = allZimiArray[Math.floor(Math.random() * allZimiArray.length)]
    const words =
      info.zimi.split('\n');
    words.forEach((item, index) => {
      if (index === 0) {
        ctx.strokeText(item, canvas.width / 2, canvas.height / 2 - 250); // 填充文字（可选，如果只需要描边可以省略）
        ctx.fillText(item, canvas.width / 2, canvas.height / 2 - 250); // 填充文字（可选，如果只需要描边可以省略）
      } else if (index === 1) {
        ctx.strokeText(item, canvas.width / 2, canvas.height / 2); // 填充文字（可选，如果只需要描边可以省略）
        ctx.fillText(item, canvas.width / 2, canvas.height / 2); // 填充文字（可选，如果只需要描边可以省略）
      } else if (index === 2) {
        ctx.strokeText(item, canvas.width / 2, canvas.height / 2 + 250); // 填充文字（可选，如果只需要描边可以省略）
        ctx.fillText(item, canvas.width / 2, canvas.height / 2 + 250); // 填充文字（可选，如果只需要描边可以省略）
      } else if (index === 3) {
        ctx.strokeText(item, canvas.width / 2, canvas.height / 2 + 500); // 填充文字（可选，如果只需要描边可以省略）
        ctx.fillText(item, canvas.width / 2, canvas.height / 2 + 500); // 填充文字（可选，如果只需要描边可以省略）
      }
    });
    console.log(words);
    // 转换为图片URL
    const imageURL = canvas.toDataURL('image/png');
    const imgUrl = URL.createObjectURL(dataURItoBlob(imageURL));
    info.imgUrl = imgUrl;
    endZimiVideo(info);
  } else {
    if (!allZimi.value) {
      alert('请输入字谜');
      return;
    }
    const parts = allZimi.value
      .match(/"([^"]*)"/g)
      .map((part) => part.slice(1, -1));
    parts.forEach((part, index) => {
      const canvas = document.createElement('canvas');
      canvas.width = zimiArray.value[index].width; // 画布宽
      canvas.height = zimiArray.value[index].height; // 画布高
      zimiArray.value[index].zimi = part;
      const ctx = canvas.getContext('2d');
      ctx.font = 'bold 150px Arial'; // 设置字体大小和类型
      ctx.fillStyle = '#FCDF00'; // 设置填充颜色，即文字颜色
      ctx.strokeStyle = 'black'; // 设置描边颜色
      ctx.lineWidth = 30; // 设置描边宽度
      ctx.textBaseline = 'middle'; // 设置文字基线为中间
      ctx.textAlign = 'center'; // 设置文字对齐方式为居中
      ctx.strokeText('赏你五千万也', canvas.width / 2, canvas.height / 2 - 700);
      ctx.fillText('赏你五千万也', canvas.width / 2, canvas.height / 2 - 700);
      // footer
      ctx.strokeText('猜不出', canvas.width / 2, canvas.height / 2 - 500);
      ctx.fillText('猜不出', canvas.width / 2, canvas.height / 2 - 500);
      ctx.strokeText('猜四个字', canvas.width / 2, canvas.height / 2 + 750);
      ctx.fillText('猜四个字', canvas.width / 2, canvas.height / 2 + 750);
      // 设置文字样式
      ctx.font = 'bold 180px Arial'; // 设置字体大小和类型
      ctx.fillStyle = 'white'; // 设置填充颜色，即文字颜色
      ctx.strokeStyle = 'red'; // 设置描边颜色
      ctx.lineWidth = 20; // 设置描边宽度
      ctx.textBaseline = 'middle'; // 设置文字基线为中间
      ctx.textAlign = 'center'; // 设置文字对齐方式为居中
      let words = part.split('\n'); // 使用空格作为分隔符进行分割
      words.forEach((item, index) => {
        if (index === 0) {
          ctx.strokeText(item, canvas.width / 2, canvas.height / 2 - 250); // 填充文字（可选，如果只需要描边可以省略）
          ctx.fillText(item, canvas.width / 2, canvas.height / 2 - 250); // 填充文字（可选，如果只需要描边可以省略）
        } else if (index === 1) {
          ctx.strokeText(item, canvas.width / 2, canvas.height / 2); // 填充文字（可选，如果只需要描边可以省略）
          ctx.fillText(item, canvas.width / 2, canvas.height / 2); // 填充文字（可选，如果只需要描边可以省略）
        } else if (index === 2) {
          ctx.strokeText(item, canvas.width / 2, canvas.height / 2 + 250); // 填充文字（可选，如果只需要描边可以省略）
          ctx.fillText(item, canvas.width / 2, canvas.height / 2 + 250); // 填充文字（可选，如果只需要描边可以省略）
        } else if (index === 3) {
          ctx.strokeText(item, canvas.width / 2, canvas.height / 2 + 500); // 填充文字（可选，如果只需要描边可以省略）
          ctx.fillText(item, canvas.width / 2, canvas.height / 2 + 500); // 填充文字（可选，如果只需要描边可以省略）
        }
      });
      // 转换为图片URL
      const imageURL = canvas.toDataURL('image/png');
      const imgUrl = URL.createObjectURL(dataURItoBlob(imageURL));
      zimiArray.value[index].imgUrl = imgUrl;
      endZimiVideo(zimiArray.value[index]);
    });
  }
};

const dataURItoBlob = (dataURl) => {
  var byteString = atob(dataURl.split(',')[1]);
  var mimeString = dataURl.split(',')[0].split(':')[1].split(';')[0];
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  return new Blob([ab], { type: mimeString });
};
</script>

<style lang="scss" scoped></style>